use std::collections::HashMap;
use std::sync::Arc;
use tokio::io::AsyncReadExt;
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::{mpsc, RwLock};
use tokio::sync::mpsc::Sender;
use tracing::{debug, error, info, trace};
use crate::nosql::nosql_database::{NoSqlDatabase, Task};

pub async fn run() {
    let mut db = Arc::new(RwLock::new(NoSqlDatabase::new()));

    let listener = TcpListener::bind("127.0.0.1:7423").await.unwrap();

    info!("listener in 7423");


    loop {
        debug!("trace here: socket get not start!");
        match listener.accept().await {
            Ok((socket, _)) => {
                debug!("trace here: socket get start!");

                // 使用 tokio::spawn 处理每个连接
                let db_clone = Arc::clone(&db);
                debug!("trace here: db_clone get start!");
                tokio::spawn(async move{
                    process(socket, db_clone).await;
                });
            },
            Err(e) => {
                error!("Error accepting connection: {}", e);
            }

        }

    }
}

async fn process(mut socket: TcpStream, mut db: Arc<RwLock<NoSqlDatabase>>) {
    let mut buf = [0; 2048];

    debug!("trace here: process start!");
    loop {
        match socket.read(&mut buf).await {
            Ok(n) if n == 0 => {
                info!("Connection closed");
                return;
            }
            Ok(n) => {
                // 1. 解析请求,请求入队
                let message = String::from_utf8_lossy(&buf[..n]).trim().to_string();
                debug!("trace here: message: {}", message);
                if let Some(task) = NoSqlDatabase::parse_message(&message) {
                    // 修改 socket 的传递方式
                     let mut db_read = db.write().await;
                        db_read.process_task(task, &mut socket);
                    // db.process_task(task, &mut socket);
                } else {
                    info!("Invalid message: {}", message);
                }
            }
            Err(e) => {
                info!("Error reading from socket: {}", e);
                return;
            }
        }
    }
}